#pragma once
#include <QHash>
#include <QVector>

template<typename T>
class CHistoryList
{
	struct CHistoryListNode
	{
		QString id;
		T val;
		CHistoryListNode* prevNode;
		CHistoryListNode* nextNode;
		CHistoryListNode(T _val = nullptr, QString _id = "") : val(_val), id(_id), prevNode(nullptr), nextNode(nullptr) {}
	};

	CHistoryListNode* head;
	CHistoryListNode* tail;
	QHash<QString, CHistoryListNode*> hash;
	void AddToHead(CHistoryListNode* pNode)
	{
		pNode->nextNode = head->nextNode;
		pNode->prevNode = head;
		head->nextNode->prevNode = pNode;
		head->nextNode = pNode;
	}
	void AddToTail(CHistoryListNode* pNode)
	{
		pNode->prevNode = tail->prevNode;
		pNode->nextNode = tail;
		tail->prevNode->nextNode = pNode;
		tail->prevNode = pNode;
	}
public:
	CHistoryList()
	{
		head = new CHistoryListNode();
		tail = new CHistoryListNode();
		head->nextNode = tail;
		tail->prevNode = head;
	}

	void AddToTail(T t, const QString& id)
	{
		AddToTail(new CHistoryListNode(t, id));
	}
	void AddToList(T t, QString id)
	{
		if (hash.contains(id))
		{
			CHistoryListNode* pNode = hash[id];
			pNode->prevNode->nextNode = pNode->nextNode;
			pNode->nextNode->prevNode = pNode->prevNode;
			AddToHead(pNode);
		}
		else
		{
			CHistoryListNode* pNode = new CHistoryListNode(t, id);
			hash[id] = pNode;
			AddToHead(pNode);
		}
	}

	CHistoryListNode* begin() const
	{ 
		return head->nextNode;
	}
	CHistoryListNode* end() const
	{ 
		return tail; 
	}

	QVector<T> ListToVector() const
	{
		CHistoryListNode* p = head->nextNode;
		QVector<T> qVt;
		while (p != tail)
		{
			qVt.push_back(p->val);
			p = p->nextNode;
		}
		return qVt;
	}
};
